package com.yilin.tms.order.service.order.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.*;
import com.yilin.tms.core.commons.base.BaseEntity;
import com.yilin.tms.core.commons.utils.OrderUtil;
import com.yilin.tms.core.application.PageData;
import com.yilin.tms.core.commons.model.AuthData;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.entity.gps.VehicleGps;
import com.yilin.tms.core.entity.gps.hyb.EquipmentInfo;
import com.yilin.tms.core.entity.gps.hyb.FenceInfoDTO;
import com.yilin.tms.core.entity.order.goods.GoodsOrderNote;
import com.yilin.tms.core.entity.order.goods.GoodsOrderNoteDetail;
import com.yilin.tms.core.entity.order.goods.GoodsOrder;
import com.yilin.tms.core.entity.order.payment.OrderPaymentCost;
import com.yilin.tms.core.entity.order.rob.RobOrderNote;
import com.yilin.tms.core.entity.order.rob.RobOrderNoteDetail;
import com.yilin.tms.core.entity.order.rob.RobOrder;
import com.yilin.tms.core.entity.order.transit.TransitOrderNote;
import com.yilin.tms.core.entity.order.transit.TransitOrderNoteDetail;
import com.yilin.tms.core.entity.order.transit.TransitOrder;
import com.yilin.tms.core.entity.system.param.TruckType;
import com.yilin.tms.core.entity.truck.TruckVehicle;
import com.yilin.tms.core.entity.user.OrganType;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.organize.MemberType;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.remote.IGpsRemote;
import com.yilin.tms.core.remote.IMessageRemote;
import com.yilin.tms.core.remote.IUserRemote;
import com.yilin.tms.core.remote.IVehicleRemote;
import com.yilin.tms.order.mapper.goods.GoodsOrderNoteDetailMapper;
import com.yilin.tms.order.mapper.goods.GoodsOrderNoteMapper;
import com.yilin.tms.order.mapper.rob.RobOrderNoteDetailMapper;
import com.yilin.tms.order.mapper.rob.RobOrderMapper;
import com.yilin.tms.order.mapper.rob.RobOrderNoteMapper;
import com.yilin.tms.order.mapper.transit.TransitOrderNoteDetailMapper;
import com.yilin.tms.order.mapper.transit.TransitOrderMapper;
import com.yilin.tms.order.mapper.transit.TransitOrderNoteMapper;
import com.yilin.tms.order.service.order.IGoodsService;
import com.yilin.tms.order.service.order.IRobService;
import com.yilin.tms.order.service.owner.IRobOwnerService;
import com.yilin.tms.order.service.owner.ITransitOwnerService;
import com.yilin.tms.order.service.party.IOrderAutLogService;
import com.yilin.tms.order.service.payment.IOrderPaymentCostService;
import com.yilin.tms.order.service.payment.IOrderRefundCostService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

import static com.yilin.tms.core.commons.constant.IncrementConstant.supportAutoAssign;

/**
 * 抢单
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RobService extends ServiceImpl<RobOrderMapper, RobOrder> implements IRobService {

    @Resource
    IRobOwnerService robOwnerService;
    @Resource
    IGoodsService goodsService;
    @Resource
    IOrderAutLogService orderAutLogService;
    @Resource
    ITransitOwnerService transitOwnerService;
    @Resource
    IOrderPaymentCostService orderPaymentCostService;
    @Resource
    IOrderRefundCostService orderRefundCostService;

    @Resource
    IUserRemote userRemote;
    @Resource
    IMessageRemote messageRemote;
    @Resource
    IVehicleRemote vehicleRemote;
    @Resource
    IGpsRemote gpsRemote;

    @Resource
    RobOrderMapper robOrderMapper;
    @Resource
    RobOrderNoteMapper robOrderNoteMapper;
    @Resource
    RobOrderNoteDetailMapper robOrderNoteDetailMapper;
    @Resource
    GoodsOrderNoteMapper goodsOrderNoteMapper;
    @Resource
    GoodsOrderNoteDetailMapper goodsOrderNoteDetailMapper;
    @Resource
    TransitOrderMapper transitOrderMapper;
    @Resource
    TransitOrderNoteMapper transitOrderNoteMapper;
    @Resource
    TransitOrderNoteDetailMapper transitOrderNoteDetailMapper;


    /**
     * 获取抢单分页
     */
    @Override
    public PageData<RobOrder> getRobOrderPage(Account loginUser, RobOrder query, Integer start, Integer limit) {
        List<Integer> statuses = new ArrayList<>();
        if (query.getQueryStatuses() != null && query.getQueryStatuses().length > 0) {
            List<RobOrder.RobStatus> statusList = Arrays.asList(query.getQueryStatuses());
            statuses = ArrayUtil.fieldAdd(statusList, obj -> obj.index);
        }
        PageData<RobOrder> pageData = new PageData<>(start, limit);
        pageData.addOrder(OrderItem.desc("create_time"));
        PageData<RobOrder> page = robOrderMapper.getRobOrderPage(pageData, loginUser, query, statuses);
        //批量获取个点的预付单
        List<String> idList = ArrayUtil.fieldAdd(page.getList(), BaseEntity::getId);
        if (!idList.isEmpty()) {
            List<OrderPaymentCost> robPaymentList = orderPaymentCostService.getOrderPaymentByRobOrderIds(idList);
            for (RobOrder robOrder : page.getList()) {
                OrderPaymentCost robPayment = ArrayUtil.getBy(robPaymentList, obj -> obj.getRobOrderId().equals(robOrder.getId()));
                //货主获取前台操作标识
                robOwnerService.getCanOperationMark(loginUser, robOrder, robPayment);
                //获取抢单详情链接-
                robOrder.setRobOrderDetailUrl(robOwnerService.getRobOrderDetailUrl(robOrder.getId()));
            }
        }
        return page;
    }

    /**
     * 获取抢单详情
     */
    @Override
    public RobOrder getRobOrderDetail(Account loginUser, String robOrderId) {
        RobOrder robOrder = robOrderMapper.selectById(robOrderId);
        if (robOrder == null) throw new BusinessException("未查询到该抢单");
        QueryWrapper<RobOrderNote> wrapper = new QueryWrapper<RobOrderNote>().eq("rob_order_id", robOrderId);
        List<RobOrderNote> robOrderNoteList = robOrderNoteMapper.selectList(wrapper);
        robOrderNoteList.forEach(robOrderNote -> {
            QueryWrapper<RobOrderNoteDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.eq("rob_order_note_id", robOrderNote.getId());
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteDetailMapper.selectList(detailQueryWrapper);
            robOrderNoteDetailList.forEach(robOrderNoteDetail -> {
                GoodsOrderNoteDetail goodsOrderNoteDetail = goodsOrderNoteDetailMapper.selectById(robOrderNoteDetail.getGoodsNoteDetailId());
                robOrderNoteDetail.setGoodsOrderNoteDetail(goodsOrderNoteDetail);
            });
            robOrderNote.setRobOrderNoteDetailList(robOrderNoteDetailList);
        });
        robOrder.setRobOrderNoteList(robOrderNoteList);
        //前台操作标识
        OrderPaymentCost robPayment = orderPaymentCostService.getOrderPaymentByRobOrderId(robOrderId);
        robOwnerService.getCanOperationMark(loginUser, robOrder, robPayment);
        //获取货源详情链接
        robOrder.setRobOrderDetailUrl(robOwnerService.getRobOrderDetailUrl(robOrder.getId()));
        return robOrder;
    }

    /**
     * 获取抢单列表 隐藏敏感信息
     */
    @Override
    public PageData<RobOrder> getPublicRobOrderPage(RobOrder query, Integer start, Integer limit) {
        PageData<RobOrder> page = robOrderMapper.getRobOrderPage(new PageData<>(start, limit), new Account(), query, null);
        for (RobOrder robOrder : page.getList()) {
            //隐藏敏感信息
            robOwnerService.robOrderPrivateData(robOrder);
            //获取抢单详情链接
            robOrder.setRobOrderDetailUrl(robOwnerService.getRobOrderDetailUrl(robOrder.getId()));
        }
        return page;
    }

    /**
     * 批量分配抢单
     */
    @Override
    public void batchAssignGoodsOder(Account loginUser, GoodsOrder localGoodsOrder, List<RobOrder> robOrderList) {
        robOrderList.forEach(robOrder -> {
            Organize robOrganize = ParamUtil.isSuccess(userRemote.getOrganizeById(robOrder.getRobOrganizeId()));
            Account robAccount = ParamUtil.isSuccess(userRemote.getAccountById(robOrder.getRobAccountId()));
            assignGoodsOder(loginUser, robOrder, localGoodsOrder, robOrganize, robAccount);
        });
    }

    /**
     * 分配抢单
     * 注意：若车主会员配置中含有 自动确认，这里服务里面要直接生成运单
     */
    @Override
    public void assignGoodsOder(Account loginUser, RobOrder robOrder, GoodsOrder localGoodsOrder, Organize robOrganize, Account robAccount) {
        //填充抢单基础数据
        fillInBasicData(loginUser, robOrder, robAccount, robOrganize, localGoodsOrder);
        //计算抢单量,价格,毛重,货主抢单费用
        calculateRobOrder(localGoodsOrder, robOrder);
        robOrder.setAuditCompleteTime(new Date());
        robOrder.setRobStatus(RobOrder.RobStatus.success);
        robOrderMapper.insert(robOrder);
        //保存抢单货物
        saveRobNoteDetail(loginUser, robOrder);
        //抢单成功 更新货源剩余货物量和剩余运输费
        successRobOrder(loginUser, localGoodsOrder, robOrder);
        //保存操作记录
        orderAutLogService.saveRobAutLog(robOrder.getId(), loginUser, "【分配抢单】", "抢单分配成功，等待车主确认订单并分配车辆");
        //发送通知
        String format = String.format("尊敬的司机您好，您的合作货主%s向你分配了一条抢单，请点击查看", loginUser.getName());
        messageRemote.sendOrderNotify(robAccount.getId(), format, robOwnerService.getRobOrderDetailUrl(robOrder.getId()));
        //车主支持自动派车自动生成运单
        autoAssignTransitOrder(loginUser, localGoodsOrder, robOrder);
    }

    /**
     * 申请抢单
     */
    @Override
    public RobOrder saveRobOrder(Account loginUser, RobOrder robOrder) {
        GoodsOrder localGoodsOrder = goodsService.getById(robOrder.getGoodsOrderId());
        Account robAccount = ParamUtil.isSuccess(userRemote.getAccountById(robOrder.getRobAccountId()));
        Organize robOrganize = ParamUtil.isSuccess(userRemote.getOrganizeById(robAccount.getOrganizeId()));
        //补充抢单基础信息
        fillInBasicData(loginUser, robOrder, robAccount, robOrganize, localGoodsOrder);
        //计算抢单量,价格,毛重,货主抢单费用
        calculateRobOrder(localGoodsOrder, robOrder);
        robOrderMapper.insert(robOrder);
        //保存抢单货物
        saveRobNoteDetail(loginUser, robOrder);
        //保存操作记录
        orderAutLogService.saveRobAutLog(robOrder.getId(), loginUser, "【抢单申请】", "抢单申请成功,等待货主审核");
        //抢单自动审核
        if (localGoodsOrder.getAutoAudit()) {
            robOrder.setRobStatus(RobOrder.RobStatus.success);
            auditRobOrder(loginUser, localGoodsOrder, robOrder);
        }
        String pushText;
        if (localGoodsOrder.getAutoAudit()) {
            orderAutLogService.saveRobAutLog(robOrder.getId(), loginUser, "【抢单通过】", "根据货源配置抢单自动通过");
            pushText = String.format("尊敬的货主用户您好，您的货源:%s，有一条抢单：%s 已自动通过。司机正在派车中，请耐心等待", robOrder.getGoodsOrderNo(), robOrder.getRobOrderNo());
        } else {
            pushText = String.format("尊敬的货主用户您好，您的货源：%s，有一条抢单：%s 需要您手动审核，请尽快处理", robOrder.getGoodsOrderNo(), robOrder.getRobOrderNo());
        }
        //发送推送给货主
        Account shipperAccount = userRemote.getAccountById(robOrder.getShipperAccountId()).getData();
        messageRemote.sendOrderNotify(shipperAccount.getId(), pushText, robOwnerService.getRobOrderDetailUrl(robOrder.getId()));
        return robOrder;
    }

    /**
     * 货主通过抢单
     * 注意：若车主会员配置中含有 自动确认，这里服务里面要直接生成运单
     * 根据支付位置，判断是否必须支付
     */
    @Override
    public void auditRobOrder(Account loginUser, GoodsOrder localGoodsOrder, RobOrder localRobOrder) {
        //判断抢单量是否大于货源剩余货物量
        double subDecimal = MathUtil.subtract(localGoodsOrder.getShipperTotalMeasure(), localGoodsOrder.getEmbarkMeasure());
        if (localRobOrder.getRobMeasure() > subDecimal) {
            localRobOrder.setRobStatus(RobOrder.RobStatus.back);
            localRobOrder.setAuditBackReason("货源量不足，自动退回");
            localRobOrder.setUpdateTime(new Date());
            localRobOrder.setUpdateUserId(loginUser.getId());
            updateById(localRobOrder);
            throw new BusinessException("该抢单抢单量超出剩余量，已自动退回");
        }
        localRobOrder.setUpdateTime(new Date());
        localRobOrder.setAuditCompleteTime(new Date());
        localRobOrder.setUpdateTime(new Date());
        localRobOrder.setUpdateUserId(loginUser.getId());
        robOrderMapper.updateById(localRobOrder);
        //抢单成功，更新货源运输费，作废其他无效抢单
        if (localRobOrder.getRobStatus() == RobOrder.RobStatus.success) {
            successRobOrder(loginUser, localGoodsOrder, localRobOrder);
            //车主支持自动派车自动生成运单
            autoAssignTransitOrder(loginUser, localGoodsOrder, localRobOrder);
        }
        //保存操作记录
        orderAutLogService.saveRobAutLog(localRobOrder.getId(), loginUser, localRobOrder.getRobStatus() == RobOrder.RobStatus.success ? "【抢单通过】" : "【抢单退回】",
                "抢单审核完成,审核结果:" + (localRobOrder.getRobStatus() == RobOrder.RobStatus.success ? "通过" : "退回"));
        //发送推送
        Account truckerAccount = ParamUtil.isSuccess(userRemote.getAccountById(localRobOrder.getRobAccountId()));
        String passText = String.format("尊敬的车主用户您好，您的抢单：%s，货主方已通过，请尽快分配车辆。", localRobOrder.getRobOrderNo());
        String backText = String.format("尊敬的车主用户您好，您的抢单：%s，已被货主退回，请打开APP查看退回原因。", localRobOrder.getRobOrderNo());
        String text = localRobOrder.getRobStatus() == RobOrder.RobStatus.success ? passText : backText;
        messageRemote.sendOrderNotify(truckerAccount.getId(), text, robOwnerService.getRobOrderDetailUrl(localRobOrder.getId()));
    }

    /**
     * 分配车辆 生成运单
     */
    @Override
    public String assignTruck(Account loginUser, RobOrder localRobOrder, GoodsOrder localGoodsOrder) {
        List<RobOrderNote> robOrderNoteList = localRobOrder.getRobOrderNoteList();
        Map<String, Map<RobOrderNote, List<RobOrderNoteDetail>>> truckMap = new HashMap<>();
        for (RobOrderNote robOrderNote : robOrderNoteList) {
            //拆分:存在拆分货物，以拆分货物生成运单，否则，保存元抢单货物
            robOrderNote.setRobOrderNoteDetailList(splitRobNoteDetail(robOrderNote.getRobOrderNoteDetailList()));
            //根据车辆ID, 把货物分类
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNote.getRobOrderNoteDetailList()) {
                truckMap.computeIfAbsent(robOrderNoteDetail.getTruckId(), s -> new HashMap<>());
                truckMap.get(robOrderNoteDetail.getTruckId()).computeIfAbsent(robOrderNote, s -> new ArrayList<>());
                RobOrderNoteDetail singleDetail = null;
                for (RobOrderNoteDetail orderDetail : truckMap.get(robOrderNoteDetail.getTruckId()).get(robOrderNote)) {
                    if (orderDetail.getGoodsNoteDetailId().equals(robOrderNoteDetail.getGoodsNoteDetailId()))
                        singleDetail = orderDetail;
                }
                if (singleDetail == null) {
                    truckMap.get(robOrderNoteDetail.getTruckId()).get(robOrderNote).add(robOrderNoteDetail);
                } else {
                    double addDecimal = MathUtil.add(singleDetail.getRobMeasure(), robOrderNoteDetail.getRobMeasure());
                    singleDetail.setRobMeasure(addDecimal);
                }
            }
        }
        // 检查车辆、司机
        List<TruckVehicle> truckVehicleList = judgeVehicleAndTruckUser(truckMap);
        String myTransitOrderId = null;
        // 根据车辆保存运单信息 这里要进行误差精算，整车模式下：要把运费误差放到最后一车消除
        for (int i = 0; i < truckVehicleList.size(); i++) {
            Map<RobOrderNote, List<RobOrderNoteDetail>> robOrderNoteMap = truckMap.get(truckVehicleList.get(i).getId());
            myTransitOrderId = saveTransitOrder(loginUser, localRobOrder, localGoodsOrder, robOrderNoteMap, truckVehicleList.get(i), i == truckVehicleList.size() - 1);
        }
        //更新抢单状态 运单中
        localRobOrder.setRobStatus(RobOrder.RobStatus.confirmed);
        localRobOrder.setUpdateUserId(loginUser.getId());
        localRobOrder.setUpdateTime(new Date());
        saveOrUpdate(localRobOrder);
        //推送
        String format = String.format("尊敬的货主用户您好，您已审核的抢单%s，司机正在前往装货点，请作好发货准备", localRobOrder.getRobOrderNo());
        messageRemote.sendOrderNotify(localGoodsOrder.getShipperAccountId(), format, robOwnerService.getRobOrderDetailUrl(localRobOrder.getId()));
        //保存操作记录
        orderAutLogService.saveRobAutLog(localRobOrder.getId(), loginUser, "【车辆分配】", String.format("车辆自动分配成功,抢单号：%S", localRobOrder.getRobOrderNo()));
        return myTransitOrderId;
    }

    /**
     * 取消抢单
     */
    @Override
    public void cancelRobOrder(Account loginUser, RobOrder robOrder) {
        robOrder.setCancelTime(new Date());
        robOrder.setUpdateTime(new Date());
        robOrder.setUpdateUserId(loginUser.getId());
        //撤销抢单成功的订单，需要还原货物，退还款项
        if (robOrder.getRobStatus() == RobOrder.RobStatus.success) {
            GoodsOrder localGoodsOrder = goodsService.getById(robOrder.getGoodsOrderId());
            //如果货源已作废，还原没有任何意义，这里只还原非作废货源
            if (localGoodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.scrap) {
                revertGoodsOrderEmbark(loginUser, robOrder, localGoodsOrder); // 还原货物
            }
            OrderPaymentCost paymentCost = orderPaymentCostService.getOrderPaymentByRobOrderId(robOrder.getId());
            if (paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.wait) {
                throw new BusinessException("抱歉，货主正在支付订单，请等待货主完成后再操作");
            }
            if (paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.complete) {
                orderRefundCostService.generateRobOrderRefund(robOrder, localGoodsOrder); //退还运费
            } else {
                orderPaymentCostService.cancelOrderPayment(paymentCost.getId(), loginUser);
            }
        }
        robOrder.setRobStatus(RobOrder.RobStatus.cancel);
        saveOrUpdate(robOrder);
        //保存操作记录
        orderAutLogService.saveRobAutLog(robOrder.getId(), loginUser, "【取消抢单】", String.format("抢单取消成功,单号:%s", robOrder.getRobOrderNo()));
        //推送消息
        String robOrderDetailUrl = robOwnerService.getRobOrderDetailUrl(robOrder.getId());
        if (loginUser.getUserType() == UserType.truckerUser) {
            String format = String.format("尊敬的货主用户您好，车主方已撤销抢单：%s，您的货源量已还原，若货源已下线请及时手动恢复上线", robOrder.getRobOrderNo());
            messageRemote.sendOrderNotify(robOrder.getShipperAccountId(), format, robOrderDetailUrl);
        } else {
            String format = String.format("尊敬的货主用户您好，平台已撤销抢单：%s，您的货源量已还原，若货源已下线请及时手动恢复上线", robOrder.getRobOrderNo());
            messageRemote.sendOrderNotify(robOrder.getShipperAccountId(), format, robOrderDetailUrl);
            String format1 = String.format("尊敬的车主用户您好，平台已撤销您的抢单：%s", robOrder.getRobOrderNo());
            messageRemote.sendOrderNotify(robOrder.getRobAccountId(), format1, robOrderDetailUrl);
        }
    }

    /**
     * 获取抢单成功的订单
     * 仅抢单成功
     */
    @Override
    public List<RobOrder> getRobSuccessListByGoodsOrderId(String goodsOrderId) {
        QueryWrapper<RobOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("goods_order_id", goodsOrderId);
        queryWrapper.eq("rob_status", RobOrder.RobStatus.success);
        return robOrderMapper.selectList(queryWrapper);
    }


    /**
     * 根据货源更新抢单状态
     */
    @Override
    public void updateRobByGoodsStatus(String goodsOrderId, RobOrder.RobStatus robStatus, Account loginUser) {
        List<RobOrder> robOrderList = robOrderMapper.selectList(new QueryWrapper<RobOrder>()
                .eq("goods_order_id", goodsOrderId).eq("rob_status", RobOrder.RobStatus.wait));
        for (RobOrder robOrder : robOrderList) {
            robOrder.setRobStatus(robStatus);
            robOrder.setAuditBackReason("货源已作废/下线");
            robOrder.setUpdateTime(new Date());
            robOrder.setUpdateUserId(loginUser.getId());
            updateById(robOrder);
            //推送
            String format = String.format("尊敬的车主用户您好，因货主方货源 %s，已作废/下线，您的抢单已失效。抢单号：%s", robOrder.getGoodsOrderNo(), robOrder.getRobOrderNo());
            messageRemote.sendOrderNotify(robOrder.getRobAccountId(), format, "");
        }
    }

    /**
     * 获取审核中的抢单
     * 待审核
     */
    @Override
    public List<RobOrder> getWaitRobByGoodsOrderId(String robAccountId, String goodsOrderId) {
        List<Integer> robStatusList = ArrayUtil.initList(RobOrder.RobStatus.wait.index);
        QueryWrapper<RobOrder> queryWrapper = new QueryWrapper<>();
        if (robAccountId != null) queryWrapper.eq("rob_account_id", robAccountId);
        queryWrapper.eq("goods_order_id", goodsOrderId);
        queryWrapper.in("rob_status", robStatusList);
        return robOrderMapper.selectList(queryWrapper);
    }

    /**
     * 获取用户今天已取消的抢单次数（主抢）
     */
    @Override
    public int getCancelNumberByUser(Account loginUser) {
        Date date = new Date();
        Date minDate = DateTimeUtil.minDate(date);
        String start = DateTimeUtil.dateToString(minDate);
        Date maxDate = DateTimeUtil.maxDate(date);
        String end = DateTimeUtil.dateToString(maxDate);
        return robOrderMapper.getCancelNumberByUser(loginUser.getId(), start, end);
    }

    /**
     * 获取组织下正在运行中抢单数据
     */
    @Override
    public List<RobOrder> getRunRobOrderByOrganizeId(String organizeId) {
        QueryWrapper<RobOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rob_status", RobOrder.RobStatus.wait, RobOrder.RobStatus.success);
        queryWrapper.and(cWrapper -> cWrapper.eq("shipper_organize_id", organizeId).or().eq("rob_organize_id", organizeId));
        return robOrderMapper.selectList(queryWrapper);
    }

    /**
     * 获取用户正在运行中抢单数据
     */
    @Override
    public List<RobOrder> getRunRobOrderByAccountId(String accountId) {
        QueryWrapper<RobOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rob_status", RobOrder.RobStatus.wait, RobOrder.RobStatus.success);
        queryWrapper.and(cQueryWrapper -> cQueryWrapper.eq("shipper_account_id", accountId).or().eq("rob_account_id", accountId));
        return robOrderMapper.selectList(queryWrapper);
    }

    /**
     * 定时任务 24小时未生成运单得抢单自动作废
     */
    @Override
    public void autoScrapRobOrder() {
        QueryWrapper<RobOrder> robOrderQueryWrapper = new QueryWrapper<>();
        robOrderQueryWrapper.and(qw -> qw.eq("rob_status", RobOrder.RobStatus.success).le("audit_complete_time", DateTimeUtil.plusDay(new Date(), -1)));
//        List<RobOrder> list = robOrderMapper.getOrderListByCancelTime(DateTimeUtil.dateToString(new Date()));
        List<RobOrder> list = robOrderMapper.selectList(robOrderQueryWrapper);
        if (ArrayUtil.isEmpty(list)) return;
        for (RobOrder robOrder : list) {
            robOrder.setRobStatus(RobOrder.RobStatus.cancel);
            robOrder.setCancelReason("超过24小时未处理，系统自动取消");
            robOrder.setCancelTime(new Date());
            robOrder.setUpdateTime(new Date());
            updateById(robOrder);
            //还原货源货物
            GoodsOrder localGoodsOrder = goodsService.getById(robOrder.getGoodsOrderId());
            QueryWrapper<RobOrderNoteDetail> wrapper = new QueryWrapper<RobOrderNoteDetail>().eq("rob_order_id", robOrder.getId());
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteDetailMapper.selectList(wrapper);
            double robOrderRobMeasure = 0;
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNoteDetailList) {
                GoodsOrderNoteDetail goodsOrderNoteDetail = goodsOrderNoteDetailMapper.selectById(robOrderNoteDetail.getGoodsNoteDetailId());
                goodsOrderNoteDetail.setEmbarkMeasure(MathUtil.subtract(goodsOrderNoteDetail.getEmbarkMeasure(),
                        robOrderNoteDetail.getRobMeasure()));
                goodsOrderNoteDetail.setUpdateTime(new Date());
                goodsOrderNoteDetailMapper.updateById(goodsOrderNoteDetail);
                robOrderRobMeasure = MathUtil.add(robOrderRobMeasure, robOrderNoteDetail.getRobMeasure());
            }
            localGoodsOrder.setEmbarkMeasure(MathUtil.subtract(localGoodsOrder.getEmbarkMeasure(), robOrderRobMeasure));
            //还原剩余运输费
            localGoodsOrder.setSurplusTransportCost(MathUtil.add(localGoodsOrder.getSurplusTransportCost()
                    , robOrder.getRobTransportCost()));
            localGoodsOrder.setUpdateTime(new Date());
            goodsService.updateById(localGoodsOrder);
        }
    }

    /**
     * 内部 填充抢单基础数据
     */
    private void fillInBasicData(Account loginUser, RobOrder robOrder, Account robAccount, Organize robOrganize, GoodsOrder localGoodsOrder) {
        MemberType truckerMemberType = ParamUtil.isSuccess(userRemote.getMyMemberTypeByOrganizeId(robOrder.getRobOrganizeId()));
        //平台信息
//        robOrder.setZonePlatId(localGoodsOrder.getZonePlatId());
//        robOrder.setZonePlatName(localGoodsOrder.getZonePlatName());
//        robOrder.setPlatId(localGoodsOrder.getPlatId());
//        robOrder.setPlatName(localGoodsOrder.getPlatName());
        //基础信息
        robOrder.setRobOrderNo(DateTimeUtil.dateNo("OR"));
        robOrder.setRobStatus(RobOrder.RobStatus.wait);
        if (robOrder.getRobType() == null) robOrder.setRobType(RobOrder.RobType.robing);
        robOrder.setCreateTime(new Date());
        robOrder.setAddUserId(loginUser.getId());

        //货源信息
        robOrder.setGoodsOrderId(localGoodsOrder.getId());
        robOrder.setGoodsOrderNo(localGoodsOrder.getGoodsOrderNo());
        robOrder.setGoodsOrderType(localGoodsOrder.getGoodsOrderType());
        robOrder.setPriceMode(localGoodsOrder.getPriceMode());
        robOrder.setSettlementType(localGoodsOrder.getSettlementType());
        robOrder.setLoadingTime(localGoodsOrder.getLoadingTime());
        robOrder.setShipperTotalMeasure(localGoodsOrder.getShipperTotalMeasure());
        robOrder.setMeasureUnit(localGoodsOrder.getMeasureUnit());
        robOrder.setTruckTypeIds(localGoodsOrder.getTruckTypeIds());
        robOrder.setTruckTypeNames(localGoodsOrder.getTruckTypeNames());
        robOrder.setTransportTypeId(localGoodsOrder.getTransportTypeId());
        robOrder.setTransportTypeName(localGoodsOrder.getTransportTypeName());
        robOrder.setTransportTypeCode(localGoodsOrder.getTransportTypeCode());
        robOrder.setGoodsTypeName(localGoodsOrder.getGoodsTypeName());
        robOrder.setShipperTransportCost(localGoodsOrder.getShipperTransportCost());
        //货源配置
        robOrder.setFullLoad(localGoodsOrder.getFullLoad());
        robOrder.setMatching(localGoodsOrder.getMatching());
        robOrder.setIncludedTax(localGoodsOrder.getIncludedTax());
        robOrder.setNoBargain(localGoodsOrder.getNoBargain());
        robOrder.setAutoAudit(localGoodsOrder.getAutoAudit());
        //货主信息
        robOrder.setShipperOrganizeLogo(localGoodsOrder.getShipperOrganizeLogo());
        robOrder.setShipperOrganizeId(localGoodsOrder.getShipperOrganizeId());
        robOrder.setShipperOrganizeName(localGoodsOrder.getShipperOrganizeName());
        robOrder.setShipperOrganizeType(localGoodsOrder.getShipperOrganizeType());
        robOrder.setShipperAccountId(localGoodsOrder.getShipperAccountId());
        robOrder.setShipperAccountName(localGoodsOrder.getShipperAccountName());
        robOrder.setShipperAccountAvatar(localGoodsOrder.getShipperAccountAvatar());
        robOrder.setShipperAccountPhone(localGoodsOrder.getShipperAccountPhone());
        robOrder.setShipperGroupOrganizeId(localGoodsOrder.getShipperGroupOrganizeId());
        robOrder.setShipperGroupOrganizeName(localGoodsOrder.getShipperGroupOrganizeName());
        robOrder.setShipperMemberTypeName(localGoodsOrder.getShipperMemberTypeName());
        robOrder.setShipperMonthlyRating(localGoodsOrder.getShipperMonthlyRating());
        //抢单人信息
        robOrder.setRobOrganizeLogo(robOrganize.getOrganizeLogo());
        robOrder.setRobOrganizeId(robOrganize.getId());
        robOrder.setRobOrganizeName(robOrganize.getOrganizeName());
        robOrder.setRobGroupId(robOrganize.getGroupOrganizeId());
        robOrder.setRobAccountId(robAccount.getId());
        robOrder.setRobAccountName(robAccount.getName());
        robOrder.setRobAccountPhone(robAccount.getPhone());
        robOrder.setRobAccountAvatar(robAccount.getAvatar());
        robOrder.setRobMemberTypeName(robOrganize.getMemberTypeName());
        robOrder.setRobMonthlyRating(robOrganize.getMonthlyRating());
        //锁定车主费率
        if (robOrder.getMatching()) {
            robOrder.setTruckerFeeRate(truckerMemberType.getTruckerMatchFeeRate());
        } else {
            robOrder.setTruckerFeeRate(truckerMemberType.getTruckerCarrierFeeRate());
        }
        robOrder.setAddedTaxRate(truckerMemberType.getAddedTaxRate());
        robOrder.setCityTaxRate(truckerMemberType.getCityTaxRate());
        robOrder.setLocalEduTaxRate(truckerMemberType.getLocalEduTaxRate());
        robOrder.setEduAddTaxRate(truckerMemberType.getEduAddTaxRate());
        robOrder.setIncomeTaxRate(truckerMemberType.getIncomeTaxRate());
        //抢单量 费用
        robOrder.setRobMeasure(0D);
        robOrder.setRobTransportCost(0D);
    }

    /**
     * 内部 计算抢单量,价格,毛重,货主抢单费用
     */
    private void calculateRobOrder(GoodsOrder goodsOrder, RobOrder robOrder) {
        double robMeasure = 0.00;
        double robTransportCost = 0.00;
        double robGrossWeight = 0.00;
        boolean goodsConfigure = goodsOrder.getPriceMode() != GoodsOrder.PriceMode.notPrice &&
                (goodsOrder.getAutoAudit() || goodsOrder.getNoBargain());
        for (RobOrderNote robOrderNote : robOrder.getRobOrderNoteList()) {
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNote.getRobOrderNoteDetailList()) {
                ParamUtil.isNull(robOrderNoteDetail.getGoodsNoteDetailId(), "抢单资源出错");
                ParamUtil.isNull(robOrderNoteDetail.getRobMeasure(), "抢单量不能未空");
                if (robOrderNoteDetail.getRobMeasure() == 0D) throw new BusinessException("抢单量不能为0");
                //消除抢单量误差，保留3位
                robOrderNoteDetail.setRobMeasure(MathUtil.round(robOrderNoteDetail.getRobMeasure(), 3));
                GoodsOrderNoteDetail goodsOrderNoteDetail = goodsOrderNoteDetailMapper.selectById(robOrderNoteDetail.getGoodsNoteDetailId());
                if (goodsConfigure && !goodsOrder.getFullLoad() && (!robOrderNoteDetail.getRobUnitPrice().equals(goodsOrderNoteDetail.getGoodsUnitPrice())))
                    throw new BusinessException("货源不允许议价");
                if (goodsOrder.getFullLoad() && (!robOrderNoteDetail.getRobMeasure().equals(goodsOrderNoteDetail.getGoodsMeasure())))
                    throw new BusinessException("整车货源抢单量必须等于发布量");
                robOrderNoteDetail.setMeasureUnit(goodsOrderNoteDetail.getMeasureUnit());
                double subDecimal = MathUtil.subtract(goodsOrderNoteDetail.getGoodsMeasure(), goodsOrderNoteDetail.getEmbarkMeasure());
                if (robOrderNoteDetail.getRobMeasure() > subDecimal) throw new BusinessException("货源货物不足");
                /// 计算毛重 计算抢单比例 以计算毛重
                double robRate = MathUtil.divide(robOrderNoteDetail.getRobMeasure(), goodsOrderNoteDetail.getGoodsMeasure(), 3);
                double grossWeight = MathUtil.multiply(goodsOrderNoteDetail.getGrossWeight(), robRate,2);
                robOrderNoteDetail.setRobGrossWeight(grossWeight);
                // 计算抢单 价格，只有单价计价模式需要计算单个货物的运费
                double transCost = MathUtil.multiply(robOrderNoteDetail.getRobMeasure(), robOrderNoteDetail.getRobUnitPrice(),2);
                robOrderNoteDetail.setRobTransportCost(transCost);
                // 累加货物量/毛重/单价计价抢单运输费
                robMeasure = MathUtil.add(robMeasure, robOrderNoteDetail.getRobMeasure());
                robGrossWeight = MathUtil.add(robGrossWeight, grossWeight);
                robTransportCost = MathUtil.add(robTransportCost, transCost);
            }
        }
        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.wholePrice) {
            if (goodsOrder.getShipperTotalMeasure() != robMeasure) {
                throw new BusinessException("整车计价模式下，抢单量必须等于货物量");
            }
            // ## 适用于前台抢单未报价，抢单运输费自动等于货源运输费
            robOrder.setRobTransportCost(goodsOrder.getShipperTransportCost());
        } else { // ### 仅单价计价需要计算总抢单运输费
            robOrder.setRobTransportCost(robTransportCost);
        }
        robOrder.setRobMeasure(robMeasure);
        robOrder.setRobGrossWeight(robGrossWeight);
        //计算货主基于抢单需支付运费、货主基于抢单已经付款费用、附加费、保费
        robOrder.setAdditionalDetails(goodsOrder.getShipperAdditionalDetails());
    }

    /**
     * 内部 保存抢单节点信息
     */
    public void saveRobNoteDetail(Account loginUser, RobOrder robOrder) {
        //保存抢单资源
        List<RobOrderNote> robOrderNoteList = robOrder.getRobOrderNoteList();
        robOrderNoteList.forEach(robOrderNote -> {
            List<RobOrderNoteDetail> noteDetailList = robOrderNote.getRobOrderNoteDetailList();
            GoodsOrderNote goodsOrderNote = goodsOrderNoteMapper.selectById(robOrderNote.getGoodsOrderNoteId());
            robOrderNote.setGoodsOrderId(robOrder.getGoodsOrderId());
            robOrderNote.setRobOrderId(robOrder.getId());
//            robOrderNote.setPlatId(robOrder.getPlatId());
//            robOrderNote.setPlatName(robOrder.getPlatName());
//            robOrderNote.setZonePlatId(robOrder.getZonePlatId());
//            robOrderNote.setZonePlatName(robOrder.getZonePlatName());
            robOrderNote.setAddUserId(loginUser.getId());
            robOrderNote.setCreateTime(new Date());
            robOrderNote.setConsignorArea(goodsOrderNote.getConsignorArea());
            robOrderNote.setConsignorName(goodsOrderNote.getConsignorName());
            robOrderNote.setConsignorPhone(goodsOrderNote.getConsignorPhone());
            robOrderNote.setConsignorCoordinate(goodsOrderNote.getConsignorCoordinate());
            robOrderNote.setConsignorAddress(goodsOrderNote.getConsignorAddress());
            robOrderNote.setConsignorAdCode(goodsOrderNote.getConsignorAdCode());
            robOrderNote.setConsigneeArea(goodsOrderNote.getConsigneeArea());
            robOrderNote.setConsigneeName(goodsOrderNote.getConsigneeName());
            robOrderNote.setConsigneePhone(goodsOrderNote.getConsigneePhone());
            robOrderNote.setConsigneeCoordinate(goodsOrderNote.getConsigneeCoordinate());
            robOrderNote.setConsigneeAddress(goodsOrderNote.getConsigneeAddress());
            robOrderNote.setConsigneeAdCode(goodsOrderNote.getConsigneeAdCode());
            robOrderNote.setMeasureUnit(goodsOrderNote.getMeasureUnit());
            robOrderNote.setRobNoteMeasure(ArrayUtil.numListAdd(noteDetailList, RobOrderNoteDetail::getRobMeasure));
            robOrderNote.setRobNoteTransportCost(ArrayUtil.numListAdd(noteDetailList, RobOrderNoteDetail::getRobTransportCost));
            robOrderNoteMapper.insert(robOrderNote);
            ArrayUtil.forEach(noteDetailList, robNoteDetail -> {
                GoodsOrderNoteDetail goodsDetail = goodsOrderNoteDetailMapper.selectById(robNoteDetail.getGoodsNoteDetailId());
                robNoteDetail.setGoodsTypeName(goodsDetail.getGoodsTypeName());
                robNoteDetail.setGoodsName(goodsDetail.getGoodsName());
                robNoteDetail.setGoodsDescribe(goodsDetail.getGoodsDescribe());
//                robNoteDetail.setPlatId(robOrder.getPlatId());
//                robNoteDetail.setPlatName(robOrder.getPlatName());
//                robNoteDetail.setZonePlatId(robOrder.getZonePlatId());
//                robNoteDetail.setZonePlatName(robOrder.getZonePlatName());
                robNoteDetail.setGoodsOrderId(robOrder.getGoodsOrderId());
                robNoteDetail.setRobOrderId(robOrder.getId());
                robNoteDetail.setRobOrderNoteId(robOrderNote.getId());
                robNoteDetail.setAddUserId(loginUser.getId());
                robNoteDetail.setCreateTime(new Date());
                robNoteDetail.setMeasureUnit(goodsDetail.getMeasureUnit());
                robNoteDetail.setCargoUnitPrice(goodsDetail.getCargoUnitPrice());
                robNoteDetail.setCargoThreshold(goodsDetail.getCargoThreshold());
                robOrderNoteDetailMapper.insert(robNoteDetail);
            });
        });
        robOrder.setRobMeasure(ArrayUtil.numListAdd(robOrderNoteList, RobOrderNote::getRobNoteMeasure));
        robOrder.setUpdateTime(new Date());
        robOrder.setUpdateUserId(loginUser.getId());
        //生成标题
        robOrder.setTitle(OrderUtil.genOrderTitle(ArrayUtil.first(robOrder.getRobOrderNoteList())));
        //始发点、终点信息
        RobOrderNote firstOrderNote = ArrayUtil.first(robOrder.getRobOrderNoteList());
        robOrder.setDisplayConsignorArea(firstOrderNote.getConsignorArea());
        robOrder.setDisplayConsigneeArea(firstOrderNote.getConsigneeArea());
        robOrderMapper.updateById(robOrder);
    }

    //内部 抢单成功处理
    private void successRobOrder(Account loginUser, GoodsOrder goodsOrder, RobOrder robOrder) {
        //更新货源剩余货物量和剩余运输费
        updateGoodsOrderEmbark(loginUser, goodsOrder, robOrder);
        //生成抢单运输预支付订单
        OrderPaymentCost orderPaymentCost = orderPaymentCostService.generateRobOrderPayment(robOrder, goodsOrder);
        robOrder.setPayCost(MathUtil.add(robOrder.getPayCost(), orderPaymentCost.getPayCost()));
        robOrderMapper.updateById(robOrder);
        //作废货源其他抢单量大于货源剩余量的未审核抢单
        QueryWrapper<RobOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("goods_order_id", robOrder.getGoodsOrderId());
        orderQueryWrapper.eq("rob_status", RobOrder.RobStatus.wait.index);
        List<RobOrder> otherRobOrderList = robOrderMapper.selectList(orderQueryWrapper);
        //货单剩余量
        double surplusMeasure = MathUtil.subtract(goodsOrder.getShipperTotalMeasure(), goodsOrder.getEmbarkMeasure());
        otherRobOrderList.forEach(otherRobOrder -> {
            if (otherRobOrder.getId().equals(robOrder.getId())) return;
            if (otherRobOrder.getRobMeasure() <= surplusMeasure) return;
            otherRobOrder.setRobStatus(RobOrder.RobStatus.back);
            otherRobOrder.setAuditBackReason("货主审核了其他抢单导致货源剩余量不足，您的抢单被自动退回");
            otherRobOrder.setUpdateUserId(loginUser.getId());
            otherRobOrder.setUpdateTime(new Date());
            //保存操作记录
            orderAutLogService.saveRobAutLog(otherRobOrder.getId(), loginUser,
                    "【抢单退回】", "货主审核了其他抢单导致货源剩余量不足，您的抢单被自动退回");
        });
    }

    //内部 更新货源剩余货物量和剩余运输费
    private void updateGoodsOrderEmbark(Account loginUser, GoodsOrder goodsOrder, RobOrder robOrder) {
        if (robOrder.getRobStatus() != RobOrder.RobStatus.success) return;
        double totalEmbarkMeasure = 0.00;
        QueryWrapper<RobOrderNote> noteWrapper = new QueryWrapper<RobOrderNote>().eq("rob_order_id", robOrder.getId());
        List<RobOrderNote> robOrderNoteList = robOrderNoteMapper.selectList(noteWrapper);
        for (RobOrderNote robOrderNote : robOrderNoteList) {
            double noneEmbarkMeasure = 0.00;
            QueryWrapper<RobOrderNoteDetail> wrapper = new QueryWrapper<RobOrderNoteDetail>().eq("rob_order_note_id", robOrderNote.getId());
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteDetailMapper.selectList(wrapper);
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNoteDetailList) {
                GoodsOrderNoteDetail goodsOrderNoteDetail = goodsOrderNoteDetailMapper.selectById(robOrderNoteDetail.getGoodsNoteDetailId());
                double addDecimal = MathUtil.add(goodsOrderNoteDetail.getEmbarkMeasure(), robOrderNoteDetail.getRobMeasure());
                goodsOrderNoteDetail.setEmbarkMeasure(addDecimal);
                goodsOrderNoteDetail.setUpdateTime(new Date());
                goodsOrderNoteDetail.setUpdateUserId(loginUser.getId());
                goodsOrderNoteDetailMapper.updateById(goodsOrderNoteDetail);
                noneEmbarkMeasure = MathUtil.add(noneEmbarkMeasure, robOrderNoteDetail.getRobMeasure());
            }
            GoodsOrderNote goodsOrderNote = goodsOrderNoteMapper.selectById(robOrderNote.getGoodsOrderNoteId());
            goodsOrderNote.setGoodsNoteEmbarkMeasure(noneEmbarkMeasure);
            goodsOrderNote.setUpdateTime(new Date());
            goodsOrderNote.setUpdateUserId(loginUser.getId());
            goodsOrderNoteMapper.updateById(goodsOrderNote);
            totalEmbarkMeasure = MathUtil.add(totalEmbarkMeasure, goodsOrderNote.getGoodsNoteEmbarkMeasure());
        }
        goodsOrder.setEmbarkMeasure(MathUtil.add(goodsOrder.getEmbarkMeasure(), totalEmbarkMeasure));
        //------------------------------------------------------------------------------------------------------------------
        //-开始拆分费用 注意：货物EmbarkMeasure裝載量最大時，代表貨源完成
        if (CommonUtil.doubleTwo(goodsOrder.getEmbarkMeasure()) < CommonUtil.doubleTwo(goodsOrder.getShipperTotalMeasure())) {
            double splitRatio = MathUtil.divide(robOrder.getRobMeasure(), goodsOrder.getShipperTotalMeasure(), 3);
            robOrder.setInsuredAmount(MathUtil.multiply(goodsOrder.getInsuredAmount(), splitRatio, 2));
            robOrder.setInsuredCost(MathUtil.multiply(goodsOrder.getInsuredCost(), splitRatio, 2));
            robOrder.setAdditionalCost(MathUtil.multiply(goodsOrder.getShipperAdditionalCost(), splitRatio, 2));
            robOrder.setPayCost(MathUtil.multiply(goodsOrder.getPayCost(), splitRatio, 2));
        } else {
            robOrder.setInsuredAmount(MathUtil.subtract(goodsOrder.getInsuredAmount(), goodsOrder.getEmbarkInsuranceAmount()));
            robOrder.setInsuredCost(MathUtil.subtract(goodsOrder.getInsuredCost(), goodsOrder.getEmbarkAdditionalCost()));
            robOrder.setAdditionalCost(MathUtil.subtract(goodsOrder.getShipperAdditionalCost(), goodsOrder.getEmbarkAdditionalCost()));
            robOrder.setPayCost(MathUtil.subtract(goodsOrder.getPayCost(), goodsOrder.getEmbarkAlreadyPayCost()));
        }
        //---------------------------------------------------------------------------------------------------------------
        //更新已抢装载信息  //累计拆分费用
        goodsOrder.setEmbarkAdditionalCost(MathUtil.add(goodsOrder.getEmbarkAdditionalCost(), robOrder.getAdditionalCost()));
        goodsOrder.setEmbarkInsuranceCost(MathUtil.add(goodsOrder.getEmbarkInsuranceCost(), robOrder.getInsuredCost()));
        goodsOrder.setEmbarkInsuranceAmount(MathUtil.add(goodsOrder.getEmbarkInsuranceAmount(), robOrder.getInsuredAmount()));
        goodsOrder.setEmbarkAlreadyPayCost(MathUtil.add(goodsOrder.getEmbarkAlreadyPayCost(), robOrder.getAdditionalCost()));

        //已装量=货源量 货源作废
        if (goodsOrder.getEmbarkMeasure() >= goodsOrder.getShipperTotalMeasure()) {
            goodsOrder.setGoodsStatus(GoodsOrder.GoodsStatus.scrap);
        }
        //货源剩余运输费
        goodsOrder.setSurplusTransportCost(MathUtil.subtract(goodsOrder.getSurplusTransportCost(), robOrder.getRobTransportCost()));
        goodsOrder.setUpdateUserId(loginUser.getId());
        goodsOrder.setUpdateTime(new Date());
        goodsService.saveOrUpdate(goodsOrder);
    }

    //内部：还原货源 节点 货物
    private void revertGoodsOrderEmbark(Account loginUser, RobOrder robOrder, GoodsOrder localGoodsOrder) {
        double totalRobOrderRobMeasure = 0;
        QueryWrapper<RobOrderNote> noteWrapper = new QueryWrapper<RobOrderNote>().eq("rob_order_id", robOrder.getId());
        List<RobOrderNote> robOrderNoteList = robOrderNoteMapper.selectList(noteWrapper);
        for (RobOrderNote robOrderNote : robOrderNoteList) {
            double noteRobOrderRobMeasure = 0;
            QueryWrapper<RobOrderNoteDetail> detailWrapper = new QueryWrapper<RobOrderNoteDetail>().eq("rob_order_note_id", robOrderNote.getId());
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteDetailMapper.selectList(detailWrapper);
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNoteDetailList) {
                GoodsOrderNoteDetail goodsOrderNoteDetail = goodsOrderNoteDetailMapper.selectById(robOrderNoteDetail.getGoodsNoteDetailId());
                goodsOrderNoteDetail.setEmbarkMeasure(MathUtil.subtract(goodsOrderNoteDetail.getEmbarkMeasure(), robOrderNoteDetail.getRobMeasure()));
                goodsOrderNoteDetail.setUpdateUserId(loginUser.getId());
                goodsOrderNoteDetail.setUpdateTime(new Date());
                goodsOrderNoteDetailMapper.updateById(goodsOrderNoteDetail);
                noteRobOrderRobMeasure = MathUtil.add(noteRobOrderRobMeasure, robOrderNoteDetail.getRobMeasure());
            }
            GoodsOrderNote goodsOrderNote = goodsOrderNoteMapper.selectById(robOrderNote.getGoodsOrderNoteId());
            goodsOrderNote.setGoodsNoteEmbarkMeasure(MathUtil.subtract(goodsOrderNote.getGoodsNoteEmbarkMeasure(), noteRobOrderRobMeasure));
            goodsOrderNoteMapper.updateById(goodsOrderNote);
            totalRobOrderRobMeasure = MathUtil.add(totalRobOrderRobMeasure, goodsOrderNote.getGoodsNoteEmbarkMeasure());
        }
        localGoodsOrder.setEmbarkMeasure(MathUtil.subtract(localGoodsOrder.getEmbarkMeasure(), totalRobOrderRobMeasure));
        //-----------------------------------------------------------------------------------------------------------------------------------
        //还原货物时，抢单反向还原拆分费用
        localGoodsOrder.setEmbarkAdditionalCost(MathUtil.subtract(localGoodsOrder.getEmbarkAdditionalCost(), robOrder.getAdditionalCost()));
        localGoodsOrder.setEmbarkInsuranceCost(MathUtil.subtract(localGoodsOrder.getEmbarkInsuranceCost(), robOrder.getInsuredCost()));
        localGoodsOrder.setEmbarkInsuranceAmount(MathUtil.subtract(localGoodsOrder.getEmbarkInsuranceAmount(), robOrder.getInsuredAmount()));
        localGoodsOrder.setEmbarkAlreadyPayCost(MathUtil.subtract(localGoodsOrder.getEmbarkAlreadyPayCost(), robOrder.getAdditionalCost()));

        //还原剩余运输费
        localGoodsOrder.setSurplusTransportCost(MathUtil.add(localGoodsOrder.getSurplusTransportCost(), robOrder.getRobTransportCost()));
        localGoodsOrder.setUpdateUserId(loginUser.getId());
        localGoodsOrder.setUpdateTime(new Date());
        goodsService.saveOrUpdate(localGoodsOrder);
    }

    //内部 车主支持自动派车自动生成运单
    private void autoAssignTransitOrder(Account loginUser, GoodsOrder localGoodsOrder, RobOrder robOrder) {
        if (!localGoodsOrder.getFullLoad()) return;
        MemberType memberType = ParamUtil.isSuccess(userRemote.getMyMemberTypeConfig(loginUser.getOrganizeId()));
        if (!memberType.getIncrementMap().get(supportAutoAssign)) return;
        //先检查是否需要支付，需要支付时，不能自动派车
        if (memberType.getRobPaymentRate() > 0) return;
        //获取车主空闲车辆
        Account truckerAccount = ParamUtil.isSuccess(userRemote.getAccountById(robOrder.getRobAccountId()));
        List<TruckVehicle> truckVehicleList = ParamUtil.isSuccess(vehicleRemote.getUnUsedVehicleListByOrganizeId(truckerAccount.getOrganizeId()));
        //没有车辆时，取消自动派车
        if (truckVehicleList == null || truckVehicleList.isEmpty()) return;
        List<TruckVehicle> autoTruckVehicleList = new ArrayList<>();
        //找到符合货源车辆类型的空闲车辆
        for (TruckVehicle truckVehicle : truckVehicleList) {
            if (truckVehicle.getTruckUserId() == null) continue;
            if (StringUtil.isEmpty(localGoodsOrder.getTruckTypeIds())) {
                autoTruckVehicleList.add(truckVehicle);
            } else {
                String[] splitIds = localGoodsOrder.getTruckTypeIds().split(",");
                if (!Arrays.asList(splitIds).contains(truckVehicle.getCommTruckTypeId())) continue;
                if (truckVehicle.getLoadingWeight() > robOrder.getRobGrossWeight()) continue;
                autoTruckVehicleList.add(truckVehicle);
            }
        }
        //无符合车辆或存在多个符合车辆时，取消自动派车
        if (autoTruckVehicleList.size() != 1) return;
        QueryWrapper<RobOrderNote> noteWrapper = new QueryWrapper<RobOrderNote>().eq("rob_order_id", robOrder.getId());
        List<RobOrderNote> robOrderNoteList = robOrderNoteMapper.selectList(noteWrapper);
        for (RobOrderNote robOrderNote : robOrderNoteList) {
            QueryWrapper<RobOrderNoteDetail> wrapper = new QueryWrapper<RobOrderNoteDetail>().eq("rob_order_note_id", robOrderNote.getId());
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteDetailMapper.selectList(wrapper);
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNoteDetailList) {
                robOrderNoteDetail.setTruckId(autoTruckVehicleList.get(0).getId());
                robOrderNoteDetail.setSplit(false);
            }
            robOrderNote.setRobOrderNoteDetailList(robOrderNoteDetailList);
        }
        robOrder.setRobOrderNoteList(robOrderNoteList);
        //### 帮助车主分配车辆并生成运单
        assignTruck(loginUser, robOrder, localGoodsOrder);
    }

    /**
     * 内部 拆分:存在拆分货物，以拆分货物生成运单，否则，保存主抢单货物
     */
    public List<RobOrderNoteDetail> splitRobNoteDetail(List<RobOrderNoteDetail> originalRobOrderNoteDetailList) {
        List<RobOrderNoteDetail> newSplitDetailList = new ArrayList<>();
        for (RobOrderNoteDetail robOrderNoteDetail : originalRobOrderNoteDetailList) {
            if (ArrayUtil.isNotEmpty(robOrderNoteDetail.getSplitNoteDetailList())) {
                //处理拆分货物
                double totalWav = 0;
                for (RobOrderNoteDetail splitDetail : robOrderNoteDetail.getSplitNoteDetailList()) {
                    if (splitDetail.getTruckId() == null) throw new BusinessException("存在货物未选择车辆");
                    if (splitDetail.getRobMeasure() != null && splitDetail.getRobMeasure() > 0) {
                        //必须设置元抢单货物ID
                        splitDetail.setId(robOrderNoteDetail.getId());
                        splitDetail.setGoodsNoteDetailId(robOrderNoteDetail.getGoodsNoteDetailId());
                        splitDetail.setRobOrderNoteId(robOrderNoteDetail.getRobOrderNoteId());
                        splitDetail.setRobOrderId(robOrderNoteDetail.getRobOrderId());
                        totalWav = MathUtil.add(totalWav, splitDetail.getRobMeasure());
                        newSplitDetailList.add(splitDetail);
                    }
                }
                if (totalWav != robOrderNoteDetail.getRobMeasure()) throw new BusinessException("货物分配未完成");
            } else {
                //没有进行拆分 保存当前抢单
                if (robOrderNoteDetail.getTruckId() == null) throw new BusinessException("存在货物未选择车辆");
                newSplitDetailList.add(robOrderNoteDetail);
            }
        }
        return newSplitDetailList;
    }

    /**
     * 内部 检查车辆、司机
     */
    public List<TruckVehicle> judgeVehicleAndTruckUser(Map<String, Map<RobOrderNote, List<RobOrderNoteDetail>>> truckMap) {
        List<TruckVehicle> truckVehicleList = ParamUtil.isSuccess(vehicleRemote.getVehicleListByIds(String.join(",", truckMap.keySet())));
        ///检查车辆信息
        truckVehicleList.forEach(vehicle -> {
            if (vehicle.getTrackNo().contains("挂") || vehicle.getCommTruckTypeIsTrailer() == TruckType.IsTrailer.yes)
                throw new BusinessException("不能选择挂车");
            ParamUtil.notEquals("车辆未在空闲状态", vehicle.getTruckStatus(), TruckVehicle.TruckStatus.unused);
            ParamUtil.isNull(vehicle.getTrackNo(), "未知车牌号，请重新审核车辆");
            ParamUtil.isNull(vehicle.getTruckUserId(), String.format("车辆:%s 未选择驾驶员", vehicle.getTrackNo()));
            ParamUtil.isNull(vehicle.getCommTruckTypeId(), String.format("车辆:%s 未知车辆公共车型，请重新提交审核车辆", vehicle.getTrackNo()));
            ParamUtil.isNull(vehicle.getTruckTypeId(), String.format("车辆:%s 未知车辆类型，请重新提交审核车辆", vehicle.getTrackNo()));
            ParamUtil.isNull(vehicle.getTruckEnergyTypeId(), String.format("车辆:%s 未知车辆能源类型，请重新提交审核车辆", vehicle.getTrackNo()));
            //检查司机基本信息认证是否完善
            List<AuthData.AuthItem> itemList = ArrayUtil.initList(AuthData.AuthItem.authIdCard, AuthData.AuthItem.authDrivingLicense);
            if (vehicle.getVehicleWeight() > 4.5) itemList.add(AuthData.AuthItem.authQualificationCert);
            ParamUtil.isSuccess(userRemote.checkAuthStatus(vehicle.getTruckUserId(), itemList.toArray(new AuthData.AuthItem[0])));
        });
        return truckVehicleList;
    }

    /**
     * 内部 保存运单及其货物
     */
    private String saveTransitOrder(Account loginUser, RobOrder localRobOrder, GoodsOrder localGoodsOrder,
                                    Map<RobOrderNote, List<RobOrderNoteDetail>> robOrderNoteMap, TruckVehicle truckVehicle, boolean last) {
        TransitOrder transitOrder = new TransitOrder();
        transitOrder.setTransitOrderNoteList(new ArrayList<>());
        MemberType memberType = ParamUtil.isSuccess(userRemote.getMyMemberTypeByOrganizeId(loginUser.getOrganizeId()));
        List<FenceInfoDTO> fenceInfoList = new ArrayList<>();
        //填充运单基础数据
        fillInTransitBasicData(loginUser, localGoodsOrder, localRobOrder, transitOrder, truckVehicle);
        //生成Note 计算运单量、分配运输费等
        genNoteAndCalculateTransitOrder(localRobOrder, transitOrder, robOrderNoteMap, last);
        //填充节点信息
        for (TransitOrderNote transitOrderNote : transitOrder.getTransitOrderNoteList()) {
            //填充平台信息
//            transitOrderNote.setPlatId(localGoodsOrder.getPlatId());
//            transitOrderNote.setPlatName(localGoodsOrder.getPlatName());
//            transitOrderNote.setZonePlatId(localGoodsOrder.getZonePlatId());
//            transitOrderNote.setZonePlatName(localGoodsOrder.getZonePlatName());
            //填充节点信息
            RobOrderNote robOrderNote = robOrderNoteMapper.selectById(transitOrderNote.getRobOrderNoteId());
            transitOrderNote.setConsigneeArea(robOrderNote.getConsigneeArea());
            transitOrderNote.setConsigneeName(robOrderNote.getConsigneeName());
            transitOrderNote.setConsigneePhone(robOrderNote.getConsigneePhone());
            transitOrderNote.setConsigneeCoordinate(robOrderNote.getConsigneeCoordinate());
            transitOrderNote.setConsigneeAddress(robOrderNote.getConsigneeAddress());
            transitOrderNote.setConsigneeAdCode(robOrderNote.getConsigneeAdCode());
            transitOrderNote.setConsignorArea(robOrderNote.getConsignorArea());
            transitOrderNote.setConsignorName(robOrderNote.getConsignorName());
            transitOrderNote.setConsignorPhone(robOrderNote.getConsignorPhone());
            transitOrderNote.setConsignorCoordinate(robOrderNote.getConsignorCoordinate());
            transitOrderNote.setConsignorAddress(robOrderNote.getConsignorAddress());
            transitOrderNote.setConsignorAdCode(robOrderNote.getConsignorAdCode());
            transitOrderNote.setMeasureUnit(robOrderNote.getMeasureUnit());
            //新增围栏信息
            fenceInfoList.add(FenceInfoDTO.genLoadingByTransitOrderNote(transitOrderNote, memberType.getElectronicFenceRange()));
            fenceInfoList.add(FenceInfoDTO.genReceiptByTransitOrderNote(transitOrderNote, memberType.getElectronicFenceRange()));
        }

        //判断是否同平台好运宝车辆，配置装货围栏信息
        //String platId, String transportNo, String vehicleNumber, String driverName, String fenceInfoListJson
//        if (truckVehicle.getPlatId().equals(transitOrder.getPlatId()) && truckVehicle.getTruckGpsType() == VehicleGps.TruckGpsType.hyb && truckVehicle.getGpsDeviceId() != null) {
//            EquipmentInfo equipmentInfo = ParamUtil.isSuccess(gpsRemote.getTrackDeviceInfo(truckVehicle.getPlatId(), truckVehicle.getGpsDeviceId()));
//            if (equipmentInfo != null && equipmentInfo.getStatus() != 3) {
//                ParamUtil.isSuccess(gpsRemote.storeDevicePolygon(truckVehicle.getPlatId(), transitOrder.getTransportNo(), truckVehicle.getTrackNo(), truckVehicle.getTruckUserName(), JsonUtil.objectToJson(fenceInfoList)));
//                transitOrder.setHybWorking(true);
//            }
//        }

        transitOrderMapper.insert(transitOrder);
        //保存节点，货物信息
        for (TransitOrderNote transitOrderNote : transitOrder.getTransitOrderNoteList()) {
            transitOrderNote.setAddUserId(loginUser.getId());
            transitOrderNote.setCreateTime(new Date());
            transitOrderNote.setGoodsOrderId(localGoodsOrder.getId());
            transitOrderNote.setRobOrderId(localRobOrder.getId());
            transitOrderNote.setTransitOrderId(transitOrder.getId());
            List<TransitOrderNoteDetail> transitOrderNoteDetailList = transitOrderNote.getTransitOrderNoteDetailList();
            transitOrderNote.setNoteAssignMeasure(ArrayUtil.numListAdd(transitOrderNoteDetailList, TransitOrderNoteDetail::getAssignMeasure));
            transitOrderNote.setNoteAssignTransportCost(ArrayUtil.numListAdd(transitOrderNoteDetailList, TransitOrderNoteDetail::getAssignTransportCost));
            transitOrderNote.setNoteAssignTime(new Date());
            transitOrderNote.setNoteStatus(TransitOrderNote.NoteStatus.waitLoading);
            transitOrderNoteMapper.insert(transitOrderNote);
            for (TransitOrderNoteDetail transitOrderNoteDetail : transitOrderNoteDetailList) {
                transitOrderNoteDetail.setTransitOrderId(transitOrder.getId());
                transitOrderNoteDetail.setTransitOrderNoteId(transitOrderNote.getId());
//                transitOrderNoteDetail.setPlatId(transitOrder.getPlatId());
//                transitOrderNoteDetail.setPlatName(transitOrder.getPlatName());
//                transitOrderNoteDetail.setZonePlatId(transitOrder.getZonePlatId());
//                transitOrderNoteDetail.setZonePlatName(transitOrder.getZonePlatName());
                transitOrderNoteDetail.setAddUserId(loginUser.getId());
                transitOrderNoteDetail.setCreateTime(new Date());
                transitOrderNoteDetailMapper.insert(transitOrderNoteDetail);
            }
        }
        //生成标题
        transitOrder.setTitle(OrderUtil.genOrderTitle(ArrayUtil.first(transitOrder.getTransitOrderNoteList())));
        //始发点、终点信息
        TransitOrderNote firstOrderNote = ArrayUtil.first(transitOrder.getTransitOrderNoteList());
        transitOrder.setDisplayConsignorArea(firstOrderNote.getConsignorArea());
        transitOrder.setDisplayConsigneeArea(firstOrderNote.getConsigneeArea());
        transitOrderMapper.updateById(transitOrder);

        //车辆变更运输中
        ParamUtil.isSuccess(vehicleRemote.updateVehicleStatus(truckVehicle.getId(), TruckVehicle.TruckStatus.using));
        //保存操作记录
        orderAutLogService.saveTransitAutLog(transitOrder.getId(), loginUser, "【运单分配】",
                String.format("运单已成功分配,运单号:%s,车辆:%s,司机:%s", transitOrder.getTransportNo(), truckVehicle.getTrackNo(), truckVehicle.getTruckUserName()));
        //推送
        if (transitOrder.getTransitTruckUserId().equals(loginUser.getId())) return transitOrder.getId();
        String format = String.format("尊敬的司机用户您好，您有一条新运单%s，请及时查看并前往装货地点", transitOrder.getTransportNo());
        messageRemote.sendOrderNotify(transitOrder.getTransitTruckUserId(), format, transitOwnerService.getTransitOrderDetailUrl(transitOrder.getId()));
        return null;
    }

    /**
     * 内部 填充运单基础数据
     */
    private void fillInTransitBasicData(Account loginUser, GoodsOrder goodsOrder, RobOrder robOrder, TransitOrder transitOrder, TruckVehicle truckVehicle) {
        //平台信息
//        transitOrder.setZonePlatId(robOrder.getZonePlatId());
//        transitOrder.setZonePlatName(robOrder.getZonePlatName());
//        transitOrder.setPlatId(robOrder.getPlatId());
//        transitOrder.setPlatName(robOrder.getPlatName());
        //基础信息
        transitOrder.setTransitStatus(TransitOrder.TransitStatus.waitingLoading);
        transitOrder.setTmsOrderCreateState(TransitOrder.TmsOrderCreateState.wait);
        transitOrder.setTransportNo(DateTimeUtil.dateNo("TS"));
        transitOrder.setOperateStatus(TransitOrder.OperateStatus.none);
        transitOrder.setAlreadyInvoice(false);
        transitOrder.setCreateTime(new Date());
        transitOrder.setAddUserId(loginUser.getId());
        transitOrder.setAssignTime(new Date());
        //货源信息
        transitOrder.setGoodsOrderId(goodsOrder.getId());
        transitOrder.setTitle(goodsOrder.getTitle());
        transitOrder.setGoodsOrderType(goodsOrder.getGoodsOrderType());
        transitOrder.setPriceMode(goodsOrder.getPriceMode());
        transitOrder.setSettlementType(goodsOrder.getSettlementType());
        transitOrder.setGoodsOrderNo(goodsOrder.getGoodsOrderNo());
        transitOrder.setGoodsTypeName(goodsOrder.getGoodsTypeName());
        transitOrder.setTransportTypeCode(goodsOrder.getTransportTypeCode());
        transitOrder.setMeasureUnit(goodsOrder.getMeasureUnit());
        transitOrder.setTransportTypeId(goodsOrder.getTransportTypeId());
        transitOrder.setTransportTypeName(goodsOrder.getTransportTypeName());
        transitOrder.setShipperEmbarkMeasure(goodsOrder.getEmbarkMeasure());
        transitOrder.setShipperTotalMeasure(goodsOrder.getShipperTotalMeasure());
        //货源配置
        transitOrder.setMatching(goodsOrder.getMatching());
        transitOrder.setFullLoad(goodsOrder.getFullLoad());
        transitOrder.setIncludedTax(goodsOrder.getIncludedTax());
        transitOrder.setNeedUploadShipping(goodsOrder.getNeedUploadShipping());
        transitOrder.setAutoDelivery(goodsOrder.getAutoDelivery());
        transitOrder.setNeedUploadReceipt(goodsOrder.getNeedUploadReceipt());
        transitOrder.setSkipConfirmReceipt(goodsOrder.getSkipConfirmReceipt());
        transitOrder.setHandLiquidation(goodsOrder.getHandLiquidation());
        transitOrder.setStartFence(goodsOrder.getStartFence());//未启用
        //抢单信息
        transitOrder.setRobOrderId(robOrder.getId());
        transitOrder.setRobOrderNo(robOrder.getRobOrderNo());
        transitOrder.setRobType(robOrder.getRobType());
        transitOrder.setRobRemark(robOrder.getRobRemark());
        //货主信息
        transitOrder.setShipperOrganizeId(goodsOrder.getShipperOrganizeId());
        transitOrder.setShipperOrganizeName(goodsOrder.getShipperOrganizeName());
        transitOrder.setShipperOrganizeLogo(goodsOrder.getShipperOrganizeLogo());
        transitOrder.setShipperOrganizeType(goodsOrder.getShipperOrganizeType());
        transitOrder.setShipperMemberTypeName(goodsOrder.getShipperMemberTypeName());
        transitOrder.setShipperMonthlyRating(goodsOrder.getShipperMonthlyRating());
        transitOrder.setShipperAccountId(goodsOrder.getShipperAccountId());
        transitOrder.setShipperAccountName(goodsOrder.getShipperAccountName());
        transitOrder.setShipperAccountPhone(goodsOrder.getShipperAccountPhone());
        transitOrder.setShipperAccountAvatar(goodsOrder.getShipperAccountAvatar());
        transitOrder.setShipperGroupOrganizeId(goodsOrder.getShipperGroupOrganizeId());
        transitOrder.setShipperGroupOrganizeName(goodsOrder.getShipperGroupOrganizeName());
        //车主信息
        transitOrder.setRobOrganizeId(robOrder.getRobOrganizeId());
        transitOrder.setRobOrganizeName(robOrder.getRobOrganizeName());
        transitOrder.setRobOrganizeLogo(robOrder.getRobOrganizeLogo());
        transitOrder.setRobAccountId(robOrder.getRobAccountId());
        transitOrder.setRobAccountName(robOrder.getRobAccountName());
        transitOrder.setRobAccountPhone(robOrder.getRobAccountPhone());
        transitOrder.setRobAccountAvatar(robOrder.getRobAccountAvatar());
        transitOrder.setRobGroupId(robOrder.getRobGroupId());
        transitOrder.setRobMemberTypeName(robOrder.getRobMemberTypeName());
        transitOrder.setRobMonthlyRating(robOrder.getRobMonthlyRating());
        //运输车辆
        transitOrder.setTransitTruckId(truckVehicle.getId());
        transitOrder.setVehicleImageUrl(truckVehicle.getVehicleImageUrl());
        transitOrder.setTransitTruckNo(truckVehicle.getTrackNo());
        transitOrder.setTransitTruckPlateColor(truckVehicle.getCardPlateName());
        transitOrder.setTransitTruckWeight(truckVehicle.getVehicleWeight());
        transitOrder.setTransitTruckLoadingWeight(truckVehicle.getLoadingWeight());
        transitOrder.setTransitTruckTypeId(truckVehicle.getTruckTypeId());
        transitOrder.setTransitTruckTypeName(truckVehicle.getTruckTypeName());
        transitOrder.setTransitCommTruckTypeId(truckVehicle.getCommTruckTypeId());
        transitOrder.setTransitCommTruckTypeName(truckVehicle.getCommTruckTypeName());
        transitOrder.setTransitTruckTypeImgPath(truckVehicle.getCommTruckType3dPath());
        transitOrder.setTransitTruckTowingType(truckVehicle.getTruckTypeTowingType());
        //运输司机
        transitOrder.setTransitTruckUserId(truckVehicle.getTruckUserId());
        transitOrder.setTransitTruckUserName(truckVehicle.getTruckUserName());
        transitOrder.setTransitTruckUserPhone(truckVehicle.getTruckUserPhone());
        transitOrder.setTransitTruckUserAvatar(truckVehicle.getTruckUserAvatar());
    }

    /**
     * 内部 计算运单量、分配运输费等
     */
    private void genNoteAndCalculateTransitOrder(RobOrder localRobOrder, TransitOrder transitOrder, Map<RobOrderNote, List<RobOrderNoteDetail>> robOrderNoteMap, boolean last) {
        //单价计价模式 分配量 及 分配运输费 注意：定价（一口价模式），分配运输费必定为0
        double orderAssignMeasure = 0.00;
        double orderAssignTransportCost = 0.00;
        List<TransitOrderNote> transitOrderNoteList = new ArrayList<>();
        for (RobOrderNote robOrderNote : robOrderNoteMap.keySet()) {
            TransitOrderNote transitOrderNote = new TransitOrderNote();
            transitOrderNote.setRobOrderId(localRobOrder.getId());
            transitOrderNote.setRobOrderNoteId(robOrderNote.getId());
            List<TransitOrderNoteDetail> transitOrderNoteDetailList = new ArrayList<>();
            List<RobOrderNoteDetail> robOrderNoteDetailList = robOrderNoteMap.get(robOrderNote);
            for (RobOrderNoteDetail robOrderNoteDetail : robOrderNoteDetailList) {
                RobOrderNoteDetail localRobOrderNoteDetail = robOrderNoteDetailMapper.selectById(robOrderNoteDetail.getId());
                TransitOrderNoteDetail transitOrderNoteDetail = new TransitOrderNoteDetail();
                transitOrderNoteDetail.setGoodsOrderId(robOrderNoteDetail.getGoodsOrderId());
                transitOrderNoteDetail.setRobOrderNoteId(robOrderNoteDetail.getRobOrderNoteId());
                transitOrderNoteDetail.setRobOrderId(robOrderNoteDetail.getRobOrderId());
                transitOrderNoteDetail.setGoodsTypeName(robOrderNoteDetail.getGoodsTypeName());
                transitOrderNoteDetail.setGoodsName(robOrderNoteDetail.getGoodsName());
                transitOrderNoteDetail.setGoodsDescribe(robOrderNoteDetail.getGoodsDescribe());
                transitOrderNoteDetail.setMeasureUnit(localRobOrderNoteDetail.getMeasureUnit());
                transitOrderNoteDetail.setRobOrderNoteDetailId(robOrderNoteDetail.getId());
                transitOrderNoteDetail.setGoodsOrderNoteDetailId(robOrderNoteDetail.getGoodsNoteDetailId());
                transitOrderNoteDetail.setAssignMeasure(MathUtil.round(robOrderNoteDetail.getRobMeasure(), 3));
                transitOrderNoteDetail.setTransitUnitPrice(robOrderNoteDetail.getRobUnitPrice());
                transitOrderNoteDetail.setCargoUnitPrice(localRobOrderNoteDetail.getCargoUnitPrice());
                transitOrderNoteDetail.setCargoThreshold(localRobOrderNoteDetail.getCargoThreshold());
                /// 新增：累加货物量
                double measure = transitOrderNoteDetail.getAssignMeasure();
                orderAssignMeasure = MathUtil.add(orderAssignMeasure, measure);
                ///只有单价计价才能计算单个货物的运费
                double cost = MathUtil.multiply(measure, transitOrderNoteDetail.getTransitUnitPrice(),2);
                transitOrderNoteDetail.setAssignTransportCost(cost);
                orderAssignTransportCost = MathUtil.add(orderAssignTransportCost, cost);
                transitOrderNoteDetailList.add(transitOrderNoteDetail);
            }
            transitOrderNote.setTransitOrderNoteDetailList(transitOrderNoteDetailList);
            transitOrderNoteList.add(transitOrderNote);
        }
        transitOrder.setTransitOrderNoteList(transitOrderNoteList);
        ///一口价模式，要将抢单定价按量分配到每个运单，一般情况下都是一抢一车，少数情况下，会出现整车货源被车主分配给多个车辆
        ////------------------------------------------------------------------------------------------------------------------------------------------
        if (last) {///如果是最后一车，不需要比例计算，所有剩余量必须分配，以消除误差
            transitOrder.setPricingTransportCost(MathUtil.subtract(localRobOrder.getRobTransportCost(), localRobOrder.getAssignedRobTransportCost()));
            transitOrder.setInsuredAmount(MathUtil.subtract(localRobOrder.getInsuredAmount(), localRobOrder.getAssignedInsuranceAmount()));
            transitOrder.setInsuredCost(MathUtil.subtract(localRobOrder.getInsuredCost(), localRobOrder.getAssignedInsuranceCost()));
            transitOrder.setAdditionalCost(MathUtil.subtract(localRobOrder.getAdditionalCost(), localRobOrder.getAssignedAdditionalCost()));
            transitOrder.setAssignPayCost(MathUtil.subtract(localRobOrder.getPayCost(), localRobOrder.getAssignedAlreadyPayCost()));
        } else {
            double splitRatio = MathUtil.divide(orderAssignMeasure, localRobOrder.getRobMeasure(), 3);
            transitOrder.setPricingTransportCost(MathUtil.multiply(localRobOrder.getRobTransportCost(), splitRatio, 2));
            transitOrder.setInsuredAmount(MathUtil.multiply(localRobOrder.getInsuredAmount(), splitRatio, 2));
            transitOrder.setInsuredCost(MathUtil.multiply(localRobOrder.getInsuredCost(), splitRatio, 2));
            transitOrder.setAdditionalCost(MathUtil.multiply(localRobOrder.getAdditionalCost(), splitRatio, 2));
            transitOrder.setAssignPayCost(MathUtil.multiply(localRobOrder.getPayCost(), splitRatio, 2));
        }
        //生成运单费用明细// 记录已分配完成的抢单运输费，防止运单运费累加后不等于抢单运输费，分配完成后，VehicleTransportCost=RobTransportCost
        if (localRobOrder.getPriceMode() == GoodsOrder.PriceMode.wholePrice) {
            localRobOrder.setAssignedRobTransportCost(MathUtil.add(localRobOrder.getAssignedRobTransportCost(), transitOrder.getPricingTransportCost()));
        } else if (localRobOrder.getPriceMode() == GoodsOrder.PriceMode.unitPrice) {
            localRobOrder.setAssignedRobTransportCost(MathUtil.add(localRobOrder.getAssignedRobTransportCost(), transitOrder.getAssignTransportCost()));
        } else {
            localRobOrder.setAssignedRobTransportCost(MathUtil.add(localRobOrder.getAssignedRobTransportCost(), transitOrder.getAssignTransportCost()));
        }
        //-------------------------------------------------------------------------------------------------------------------------------------
        //累计已分配费用（拆分）
        localRobOrder.setAssignedAdditionalCost(MathUtil.add(localRobOrder.getAssignedAdditionalCost(), transitOrder.getAdditionalCost()));
        localRobOrder.setAssignedInsuranceCost(MathUtil.add(localRobOrder.getAssignedInsuranceCost(), transitOrder.getInsuredCost()));
        localRobOrder.setAssignedInsuranceAmount(MathUtil.add(localRobOrder.getAssignedInsuranceAmount(), transitOrder.getInsuredAmount()));
        localRobOrder.setAssignedAlreadyPayCost(MathUtil.add(localRobOrder.getAssignedAlreadyPayCost(), transitOrder.getAssignPayCost()));

        transitOrder.setAssignMeasure(orderAssignMeasure);
        transitOrder.setAssignTransportCost(orderAssignTransportCost);
    }


}
